package com.joezj.util;

import cn.hutool.core.io.resource.ClassPathResource;
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.PictureRenderData;
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import sun.misc.BASE64Decoder;

import javax.validation.constraints.NotNull;
import java.io.*;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Word导出工具类（将查询数据填充到模板导出）
 *
 * @author: Zheng Jie
 * @version: $ WordExportUtil, V1.0 2020年12月12日 0:32 Zheng Jie Exp $
 */
public class WordExportUtil {

    /** 模板所在包 */
    private static String TEMPLATE_PACKAGE = "/wordTemplate/";

    /**
     * <p>
     *     导出模板到输出流中
     * <ul>
     * <li> templateName —— 模板文件名称
     * <ul>
     * <li> 模板文件名称：   book.docx
     * <li> 入参：          "book.docx"
     * </ul>
     * <li> dataMap —— 待填充数据
     * dataMap一般与实体对应，其中key对应模板中占位符字符，如：
     * <ul>
     * <li> 实体类属性：String name = "张三";
     * <li> 模板占位符：姓名：{{name}}
     * </ul>
     * <li> outStream —— 输出流，如：response.getOutputStream()
     * </ul>
     *</p>
     * @param templateName 项目webapp/wordTemplate目录下模板文件名称
     * @param dataMap 需要填充进模板的数据
     * @param outStream 需要被写入的流
     * @throws IOException
     */
    public static void exportWordToStream(@NotNull String templateName,@NotNull Map dataMap, @NotNull OutputStream outStream) throws IOException {
        XWPFTemplate xwpfTemplate = null;
        try{
            // 配置
            Configure config = Configure.newBuilder().build();
            // 1. 在tomcat环境下模板存放于webapp时，读取webapp目录路径作为起点
            // String path = IOUtil.webappDirPath();
            // 2. 模板存放于Rsource路径下
            String path = IOUtil.classesDirPath();
            path = path + TEMPLATE_PACKAGE  + templateName;
            InputStream stream = new FileInputStream(new File(path));
            // 编译模板，填充数据
            xwpfTemplate = XWPFTemplate
                    .compile(stream, config)
                    .render(dataMap);
            xwpfTemplate.write(outStream);
        }catch (IOException e){
            throw new RuntimeException("生成文件失败！");
        }finally {
            if(xwpfTemplate != null){
                xwpfTemplate.close();
            }
        }

    }

    /**
     * <p>
     *     导出模板到输出指定路径
     * <ul>
     * <li> templateName —— 模板文件名称
     * <ul>
     * <li> 模板文件名称：   book.docx
     * <li> 入参：          "book.docx"
     * </ul>
     * <li> dataMap —— 待填充数据
     * dataMap一般与实体对应，其中key对应模板中占位符字符，如：
     * <ul>
     * <li> 实体类属性：String name = "张三";
     * <li> 模板占位符：姓名：{{name}}
     * </ul>
     * <li> destDirPath —— 目标存放目录，如：C:\Users\Joe\Desktop\
     * </ul>
     *</p>
     * @param templateName 项目webapp/wordTemplate目录下模板文件名称
     * @param dataMap 需要填充进模板的数据
     * @param destDirPath 目标存放目录
     * @throws IOException
     */
    public static void exportWordToPath(@NotNull String templateName,@NotNull Map dataMap, @NotNull String destDirPath) throws IOException {
        XWPFTemplate xwpfTemplate = null;
        try{
            // 配置
            Configure config = Configure.newBuilder().build();
            // 1. 在tomcat环境下模板存放于webapp时，读取webapp目录路径作为起点
            // String path = IOUtil.webappDirPath();
            // 2. 模板存放于Rsource路径下
            String path = IOUtil.classesDirPath();
            path = "/Users/uncless/workspace/java-code/other/word-export/src/main/resources/wordTemplate/"+templateName; //TEMPLATE_PACKAGE  + templateName;
            InputStream stream = new FileInputStream(new File(path));
            // 编译模板，填充数据
            xwpfTemplate = XWPFTemplate
                    .compile(stream, config)
                    .render(dataMap);
            xwpfTemplate.writeToFile(destDirPath);
        }catch (IOException e){
            throw new RuntimeException("生成文件失败！");
        }finally {
            if(xwpfTemplate != null){
                xwpfTemplate.close();
            }
        }

    }
    public static byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //创建一个Buffer字符串
        byte[] buffer = new byte[6024];
        //每次读取的字符串长度，如果为-1，代表全部读取完毕
        int len = 0;
        //使用一个输入流从buffer里把数据读取出来
        while ((len = inStream.read(buffer)) != -1) {
            //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        //关闭输入流
        inStream.close();
        //把outStream里的数据写入内存
        return outStream.toByteArray();
    }

    public static void main(String[] args) throws IOException {
        Map hymap=new HashMap();
        hymap.put("01","机关事业单位及部队");
        hymap.put("02","教育");
        hymap.put("03","医疗卫生业");
        hymap.put("04","金融业");
        hymap.put("05","律师、会计师事务所等咨询");
        hymap.put("06","房地产业");

        Map zymap=new HashMap();
        hymap.put("05","05");
        hymap.put("08","08");
        hymap.put("10","10");
        hymap.put("11","11");
        hymap.put("12","12");
        hymap.put("13","13");
        hymap.put("14","14");


        hymap.put("01","01");
        hymap.put("15","15");
        hymap.put("03","03");
        hymap.put("16","16");
        hymap.put("09","09");

        Map mz=new HashMap();

        mz.put("01","汉族");
        mz.put("02","蒙古族");

        mz.put("04","藏族");
        mz.put("05","维吾尔族");
        mz.put("06","苗族");
        mz.put("07","彝族");
        mz.put("08","壮族");
        mz.put("09","布依族");
        mz.put("10","朝鲜族");
        mz.put("11","满族");
        mz.put("12","侗族");
        mz.put("13","瑶族");
        mz.put("14","白族");
        mz.put("15","土家族");
        mz.put("16","哈尼族");
        mz.put("17","哈萨克族");
        mz.put("18","傣族");
        mz.put("19","黎族");
        mz.put("20","僳僳族");
        mz.put("21","佤族");
        mz.put("22","畲族");
        mz.put("23","高山族");
        mz.put("24","拉祜族");
        mz.put("25","水族");
        mz.put("26","东乡族");
        mz.put("27","纳西族");
        mz.put("28","景颇族");
        mz.put("29","柯尔克孜族");
        mz.put("30","土族");
        mz.put("31","达斡尔族");
        mz.put("32","仫佬族");
        mz.put("33","羌族");
        mz.put("34","布朗族");
        mz.put("35","撒拉族");
        mz.put("36","毛难族");
        mz.put("37","仡佬族");
        mz.put("38","锡伯族");
        mz.put("39","阿昌族");
        mz.put("40","普米族");
        mz.put("41","塔吉克族");
        mz.put("42","怒族");
        mz.put("43","乌孜别克族");
        mz.put("44","俄罗斯族");
        mz.put("45","鄂温克族");
        mz.put("46","崩龙族");
        mz.put("47","保安族");
        mz.put("48","裕固族");
        mz.put("49","京族");
        mz.put("50","塔塔尔族");
        mz.put("51","独龙族");
        mz.put("52","鄂伦春族");
        mz.put("53","赫哲族");
        mz.put("54","门巴族");
        mz.put("55","珞巴族");
        mz.put("56","基诺族");

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            //1、获取连接对象
            conn = DBUtil.getconn();
            //2、创建statement类对象，用来执行SQL语句
            st = conn.createStatement();
            //3、创建sql查询语句
            String sql = "SELECT * FROM CARD_N WHERE rownum <=10 ";
            //4、执行sql语句并且换回一个查询的结果集
            rs = st.executeQuery(sql);
            while (rs.next()) {  //循环遍历结果集
                String aab001 = rs.getString("aab001");
                String aab002 = rs.getString("aab002");
                String aac002 = rs.getString("aac002");
                String aac003 = rs.getString("aac003");
                String adress = rs.getString("adress");
                String nation = rs.getString("nation");
                String phone = rs.getString("phone");
                String tel = rs.getString("tel");
                String 行业 = rs.getString("行业");
                String zy = rs.getString("职业");
                String 签发机关 = rs.getString("签发机关");
                String dataStart = rs.getString("证件有效开始日期");
                String dataEnd = rs.getString("CARD_VAL");
                dataEnd=dataEnd.substring(0,10).replace("-","");

                String birthday = rs.getString("aac002").substring(6,14);

                String sex = rs.getString("sex");


                File image = new File(aac002);
                try (FileOutputStream fos = new FileOutputStream(image)) {
                    byte[] buffer = new byte[1024];

                    // 获取我们的BLOB数据的二进制流
                    InputStream is = rs.getBinaryStream("bac200");

                    byte[] data = readInputStream(is);
                    //new一个文件对象用来保存图片，默认保存当前工程根目录
                    File imageFile = new File("/Users/uncless/Desktop/图片/"+aac002+".jpg");
                    //创建输出流
                    FileOutputStream outStream = new FileOutputStream(imageFile);

                    //写入数据
                    outStream.write(data);
                    //关闭输出流
                    outStream.close();
                } catch (Exception e) {

                }
                    // 生成jpeg图片


                Map<String, Object> map = new HashMap<String, Object>();
                map.put("aab001",aab001);
                map.put("aab002",aab002);
                map.put("aac002",aac002);
                map.put("ac02",aac002);
                map.put("aac003",aac003);
                map.put("ac03",aac003);
                map.put("aac003_b",aac003);
                map.put("address",adress);
                map.put("add",adress);
                map.put("zy05","〇");
                map.put("zy08","〇");
                map.put("zy10","〇");
                map.put("zy11","〇");
                map.put("zy12","〇");
                map.put("zy13","〇");
                map.put("zy14","〇");
                map.put("zy01","〇");
                map.put("zy15","〇");
                map.put("zy03","〇");
                map.put("zy16","〇");
                map.put("zy09","〇");

                map.put("zy"+(hymap.get(zy)==null?"09":zy),"●");

                map.put("sex",sex.equals("1")?"男":"女");
                map.put("se",sex.equals("1")?"男":"女");
                map.put("nation",mz.get(nation));
                map.put("nat",mz.get(nation));
                map.put("birthday",birthday);
                String str= birthday;
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                Date date = sdf.parse(str);

                SimpleDateFormat s = new SimpleDateFormat("yyyy年M月dd日");
                map.put("bir",s.format(date));
                map.put("签发机关",签发机关);
                map.put("phone",phone);
                map.put("tel",tel);

                SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd");
                Date ddataStart = sd.parse(dataStart);
                Date ddataEnd = sd.parse(dataEnd);

                SimpleDateFormat sa = new SimpleDateFormat("yyyy.M.dd");

                map.put("证件有效开始日期",sa.format(ddataStart)+"-"+sa.format(ddataEnd));
                //map.put("image",new PictureRenderData(100, 120, "/Users/uncless/workspace/java-code/other/word-export/src/main/resources/wordTemplate//img.png"));
                map.put("image",new PictureRenderData(100, 120, "/Users/uncless/Desktop/图片/"+aac002+".jpg"));
                map.put("image_a",new PictureRenderData(80, 100, "/Users/uncless/Desktop/图片/"+aac002+".jpg"));
                exportWordToPath("proposal-card.docx",map,"/Users/uncless/Desktop/生成/"+aac002+"_"+aac003+".docx");
                wordToPdf(aac002,aac003);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }


    private static boolean license = false;

    public static String wordToPdf(String aac002,String aac003) throws Exception {
        FileOutputStream os = null;
        try {
            //凭证 不然切换后有水印
            InputStream is = new ClassPathResource("/license.xml").getStream();
            License aposeLic = new License();
            aposeLic.setLicense(is);
            license = true;
            if (!license) {
                System.out.println("License验证不通过...");
                return null;
            }
            //生成一个空的PDF文件
            File file = new File("/Users/uncless/Desktop/PDF/"+aac002+"_"+aac003+".pdf");
            os = new FileOutputStream(file);
            //要转换的word文件
            Document doc = new Document("/Users/uncless/Desktop/生成/"+aac002+"_"+aac003+".docx");
            doc.save(os, SaveFormat.PDF);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
